package be.euroindicator.db;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Vector;

import org.apache.log4j.Logger;
import org.jfree.util.Log;

import be.euroindicator.Constants;
import be.euroindicator.logic.Country;
import be.euroindicator.logic.CountryManager;
import be.euroindicator.logic.Indicator;
import be.euroindicator.logic.IndicatorManager;
import be.euroindicator.logic.ValuesManager;

public class DataImporter 
{
	/**
	 * The log4J logger. See http://logging.apache.org/log4j/1.2/index.html for more info.
	 */
	private static Logger log=Logger.getLogger(new Throwable().getStackTrace()[1].getClassName());

	private CountryManager countryManager;
	private IndicatorManager indicatorManager;
	private ValuesManager valuesManager;
	private BufferedReader br;

	
	
	public DataImporter(BufferedReader br) 
	{
		this.countryManager=CountryManager.getCountryManager();
		this.indicatorManager=IndicatorManager.getIndicatorManager();
		this.valuesManager=ValuesManager.getValuesManager();
		this.br=br;
	}

	public boolean importData() throws IOException 
	{
		valuesManager.clearData();
		indicatorManager.clearData();
		
		Vector<String> tempIndicatorNames=new Vector<String>();
		
		//Two first lines
		String line1=br.readLine();
		String[] names=line1.split(Constants.sep);
		
		String line2=br.readLine();
		String[] descriptions=line2.split(Constants.sep);
		
		for (int i=2;i<names.length;i++)
		{
			String name=names[i];
			String description=descriptions[i];			
			
			tempIndicatorNames.add(name);
			
			SqlConnector sqlConnector=new SqlConnector();
			sqlConnector.newIndicator(name,description);
			sqlConnector.close();	
		}
		
		indicatorManager.init();
		SqlConnector sqlConnector=new SqlConnector();
		
		while (true)
		{
			String line=br.readLine();
			if (line==null)
				break;
			
			String[] items=line.split(Constants.sep);
			
			int year=Integer.parseInt(items[0]);
			Country country=countryManager.findCountryByName(items[1]);
			
			for (int i=2;i<items.length;i++)
			{
				Indicator indicator=indicatorManager.findIndicator(tempIndicatorNames.get(i-2));
				

				String item=items[i].trim();
				
				if (item.endsWith("e"))
				{
					double value=Double.parseDouble(item.substring(0, item.length()-1));
					sqlConnector.addValue(indicator,country,year,value,true);					
				}
				else if (!item.isEmpty())
				{
					double value=Double.parseDouble(item);
					sqlConnector.addValue(indicator,country,year,value,false);					
				}
			}
		}
		sqlConnector.close();
		return true;
	}

	public String check() 
	{		
		StringBuffer result=new StringBuffer();

		result.append("Analysis of the import file:<br/>");
		Vector<String> tempIndicatorNames=new Vector<String>();
		
		//Two first lines
		String[] names;
		String[] descriptions;
		try
		{
			String line1=br.readLine();
			names=line1.split(Constants.sep);			
			
			if ((names[0].trim().length()!=0)||(names[1].trim().length()!=0))
			{
				result.append("Error on the first line, the two first rows should be empty<br/>");
				return result.toString();				
			}
			
			result.append(names.length-2+" indicators on the first line<br/>");
		}
		catch (Exception e)
		{
			result.append("Error reading the first line<br/>");			
			return result.toString();
		}
		
		try
		{
			String line2=br.readLine();
			descriptions=line2.split(Constants.sep);
			
			if (!descriptions[0].equals("Year"))
			{
				result.append("Error on the second line, the first row should be Year<br/>");
				return result.toString();	
			}

			if (!descriptions[1].equals("Country"))
			{
				result.append("Error on the second line, the second row should be Country<br/>");
				return result.toString();	
			}

			result.append(descriptions.length-2+" descriptions on the second line<br/>");
		}
		catch (Exception e)
		{
			result.append("Error reading the second line<br/>");			
			return result.toString();
		}
		
		if (names.length!=descriptions.length)
		{
			result.append("Error : the number of indicators and the number of descriptions are not matching<br/>");
			return result.toString();
		}
		
		for (int i=2;i<names.length;i++)
		{
			tempIndicatorNames.add(names[i]);
		}

		int lineCounter=2;
		int valuesCounter=0;
		int estimatedValuesCounter=0;
		
		while (true)
		{	
			String line=null;
			lineCounter++;
			try 
			{
				line = br.readLine();
			} 
			catch (IOException e) 
			{
				log.debug("Error reading line:"+lineCounter+"<br/>");
				result.append("Error reading line:"+lineCounter+"<br/>");
				return result.toString();
			}
			
			if (line==null)
				break;
			
			String[] items=null;
			try
			{
				items=line.split(Constants.sep);				
			}
			catch (Exception e) 
			{
				log.debug("Error when splitting line:"+lineCounter+"<br/>");
				result.append("Error when splitting line:"+lineCounter+"<br/>");
				return result.toString();
			}

			try
			{
				Integer.parseInt(items[0]);
			}
			catch (NumberFormatException e)
			{
				log.debug("Error when parsing the year at line:"+lineCounter+"<br/>");
				result.append("Error when parsing the year at line:"+lineCounter+"<br/>");
				return result.toString();
			}
			
			Country country=countryManager.findCountryByName(items[1]);
			
			if (country==null)
			{
				log.debug("Unknown country at line:"+lineCounter+"<br/>");
				result.append("Unknown country at line:"+lineCounter+"<br/>");	
				return result.toString();
			}
			
			for (int i=2;i<items.length;i++)
			{
				String item=items[i].trim();
				
				if (item.endsWith("e"))
				{
					try
					{
						Double.parseDouble(item.substring(0, item.length()-1));
						estimatedValuesCounter++;
					}
					catch (Exception e)
					{
						log.debug("Error parsing the estimated value:"+item+" at line:"+lineCounter+" indicator:"+tempIndicatorNames.get(i)+"<br/>");
						result.append("Error parsing the estimated value:"+item+" at line:"+lineCounter+" indicator:"+tempIndicatorNames.get(i)+"<br/>");	
						return result.toString();
					}
				}
				else if (!item.isEmpty())
				{
					try
					{
						Double.parseDouble(item);
						valuesCounter++;
					}
					catch (Exception e)
					{
						log.debug("Error parsing the value:"+item+" at line:"+lineCounter+" indicator:"+tempIndicatorNames.get(i)+"<br/>");
						result.append("Error parsing the value:"+item+" at line:"+lineCounter+" indicator:"+tempIndicatorNames.get(i)+"<br/>");	
						return result.toString();
					}				
				}
			}
		}
		result.append("End of the analysis:<br/>");
		result.append(estimatedValuesCounter+" estimated values<br/>");
		result.append(valuesCounter+" values<br/>");
		result.append(lineCounter+" lines<br/>");
		
		return result.toString();
	}
}
